const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const cors = require('@koa/cors');
const serve = require('koa-static');
const path = require('path');
const fs = require('fs/promises');
const { initDatabase } = require('./database'); // 使用新的数据库模块
const authRoutes = require('./routes/auth.routes'); // 使用新的路由文件
const newsRoutes = require('./routes/news.routes'); // 使用新的路由文件
const fileRoutes = require('./routes/file.routes'); // 使用新的路由文件
const i18nRoutes = require('./routes/i18n.routes'); // 使用新的路由文件
const { scheduleDailyMockNewsInsertion } = require('./services/newsMockScheduler');
const { schedulePublishProcessor } = require('./services/publishScheduler');

const app = new Koa();
const router = new Router();

// 每日清理 uploads 目录：删除不以 avatar 开头的文件
async function cleanupUploads() {
  try {
    const uploadsDir = path.join(__dirname, '../uploads');
    const entries = await fs.readdir(uploadsDir, { withFileTypes: true });
    const targets = entries.filter((ent) => ent.isFile() && !ent.name.startsWith('avatar'));
    for (const ent of targets) {
      const fullPath = path.join(uploadsDir, ent.name);
      try {
        await fs.unlink(fullPath);
        console.log(`[uploads-cleanup] removed: ${ent.name}`);
      } catch (err) {
        console.error(`[uploads-cleanup] failed to remove ${ent.name}:`, err.message);
      }
    }
    console.log(`[uploads-cleanup] done. removed ${targets.length} file(s).`);
  } catch (err) {
    console.error('[uploads-cleanup] error while scanning uploads:', err.message);
  }
}

function scheduleDailyUploadsCleanup() {
  // 计划每天凌晨 3:00（本地时间）执行
  const now = new Date();
  const next = new Date(now);
  next.setHours(3, 0, 0, 0);
  if (next <= now) {
    next.setDate(next.getDate() + 1);
  }
  const initialDelay = next.getTime() - now.getTime();
  console.log(`[uploads-cleanup] scheduled first run at ${next.toString()}`);
  setTimeout(() => {
    cleanupUploads().catch(() => {});
    // 之后每 24 小时执行一次
    setInterval(() => {
      cleanupUploads().catch(() => {});
    }, 24 * 60 * 60 * 1000);
  }, initialDelay);
}

// 中间件 - 配置完整的跨域支持
app.use(cors({
  origin: '*', // 允许所有来源，生产环境可设置为具体域名
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'Origin'],
  exposeHeaders: ['X-Requested-With', 'Content-Type'],
  credentials: true,
  maxAge: 86400 // 预检请求的有效期，单位秒
}));
app.use(bodyParser());

// 启动服务器的主函数
async function startServer() {
  try {
    // 初始化数据库
    await initDatabase();

    // 注册路由
    router.use('/auth', authRoutes.routes());
    router.use('/news', newsRoutes.routes());
    router.use('/file', fileRoutes.routes());
    router.use('/i18n', i18nRoutes.routes());

    // 路由前缀
    app.use(router.routes()).use(router.allowedMethods());

    // 静态文件服务 - 公共资源
    app.use(serve(path.join(__dirname, '../public')));

    // 静态文件服务 - 用于提供上传的文件
    const staticMiddleware = serve(path.join(__dirname, '../uploads'));
    app.use(async (ctx, next) => {
      if (ctx.path.startsWith('/uploads/')) {
        // 去掉/uploads前缀后传递给静态文件中间件
        const originalPath = ctx.path;
        ctx.path = ctx.path.substring('/uploads'.length);
        await staticMiddleware(ctx, () => {});
        // 恢复原始路径
        ctx.path = originalPath;
        // 如果静态文件中间件处理了请求（状态码不是404），就不再继续执行后续中间件
        if (ctx.status !== 404) {
          return;
        }
      }
      await next();
    });

    // 健康检查接口
    router.get('/health', (ctx) => {
      ctx.body = {
        code: 200,
        message: 'Server is running',
        data: null
      };
    });

    // 启动服务器
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server is running on http://localhost:${PORT}`);
      // 启动每日清理任务
      scheduleDailyUploadsCleanup();
      // 启动每日模拟新闻插入任务
      scheduleDailyMockNewsInsertion();
      // 启动定时发布触发处理器
      schedulePublishProcessor();
    });
  } catch (error) {
    console.error('Failed to start server:', error);
    process.exit(1);
  }
}

// 启动服务器
startServer();

module.exports = app;